package cn.edu.cuit.elena.web.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.edu.cuit.elena.hdfs.HDFSManager;
import cn.edu.cuit.elena.trace.Tracer;
import cn.edu.cuit.elena.transaction.system.UserContext;
import cn.edu.cuit.elena.web.System;
import cn.edu.cuit.elena.web.service.ServiceServlet.ServiceConstants;
import cn.edu.cuit.elena.web.tool.JsonHelper;

public class HDFSViewServlet
    extends HttpServlet
{

    /**
     * 
     */
    private static final long serialVersionUID = -7730326724084445354L;

    String localPath = "d://";

    /**
     * The doGet method of the servlet. <br>
     * 
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
    {

        doPost( request, response );
    }

    /**
     * The doPost method of the servlet. <br>
     * 
     * This method is called when a form has its tag value method equals to post.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
    {

        response.setContentType( "text/html" );
        PrintWriter out = response.getWriter();
        String para = request.getParameter( "kind" );
        UserContext userContext = (UserContext) request.getSession().getAttribute( ServiceConstants.USERCONTEXT.mark() );

        if( "hdfs".equals( para ) )
        {
            List<Map<String, Object>> list5 = new LinkedList<Map<String, Object>>();
            List<Map<String, ?>> temp = new LinkedList<Map<String, ?>>();
            Map<String, Object> map = new HashMap<String, Object>();
            String rootDir = userContext.getIdentifier();
            String[] DBs = HDFSManager.instance().getAllSubDirectory( "/user/quintus/" + rootDir + "/" );
            String[] DBsFile = HDFSManager.instance().getAllFiles( "/user/quintus/" + rootDir + "/" );
            for( String s : DBsFile )
            {
                Map mapF = new HashMap<String, String>();
                mapF.put( "text", s.substring( s.lastIndexOf( "/" ) + 1 ) );
                mapF.put( "leaf", "true" );
                list5.add( mapF );
            }

            for( String DB : DBs )
            {
                Map map2 = new HashMap();
                List list = new LinkedList();
                String[] TBs = HDFSManager.instance().getAllSubDirectory( DB );

                String[] TBsFiles = HDFSManager.instance().getAllFiles( DB );
                for( String s : TBsFiles )
                {
                    Map mapT = new HashMap();
                    mapT.put( "text", s.substring( s.lastIndexOf( "/" ) + 1 ) );
                    mapT.put( "leaf", "true" );
                    list.add( mapT );
                }

                //DB json Map
                for( String TB : TBs )
                {
                    List<Map<String, Object>> list0 = new LinkedList<Map<String, Object>>();
                    String[] files = HDFSManager.instance().getAllFiles( TB );
                    //TB json MAP {text:db,children:[{file1,file2...}]}
                    Map map1 = new HashMap();
                    for( String file : files )
                    {
                        //data files;
                        Map<String, Object> map0 = new HashMap<String, Object>();
                        map0.put( "text", file.substring( file.lastIndexOf( "/" ) + 1 ) );
                        map0.put( "leaf", "true" );
                        //table add files
                        list0.add( map0 );
                    }
                    map1.put( "text", TB.substring( TB.lastIndexOf( "/" ) + 1 ) );
                    map1.put( "children", list0 );
                    list.add( map1 );
                }
                map2.put( "text", DB.substring( DB.lastIndexOf( "/" ) + 1 ) );
                map2.put( "children", list );
                list5.add( map2 );
            }

            String s = JsonHelper.getNewInstance().toJson( list5 );

            Tracer.debugTrace( HDFSViewServlet.class, "hdfs path tree json : " + s, null );
            out.write( s );
            out.flush();
            out.close();
        }
        /**
         * After add file , i should refresh the hdfs tree!!!!!!!!!!!!!!
         * */
        else if( "add".equals( para ) )
        {
            String dir = request.getParameter( "dir" );
            if( dir.trim().startsWith( "/" ) )
            {
                dir = dir.substring( 1 );
            }
            try
            {
                HDFSManager.instance().create( "/user/quintus/" + userContext.getIdentifier() + "/" + dir );
                Tracer.debugTrace( HDFSViewServlet.class,
                    "Create file : " + "/user/quintus/" + userContext.getIdentifier() + "/" + dir, null );
                out.write( "1" );
                out.close();
            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Create failed : " + e.getMessage(), e );
                out.close();
            }

        }
        else if( "delete".equals( para ) )
        {
            String dir = request.getParameter( "cpath" );
            if( dir == null || dir.equals( "" ) || dir.equals( "HDFS ROOT" ) )
            {
                out.close();
                return;
            }
            try
            {
                HDFSManager.instance().delete( dir );
                Tracer.debugTrace( HDFSViewServlet.class, "Delete file success", null );
                out.write( "1" );
                out.flush();
                out.close();
            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Delete failed : " + e.getMessage(), e );
                out.close();
            }
        }
        else if( "movetolocal".equals( para ) )
        {
            String src = request.getParameter( "src" );
            String tar = request.getParameter( "tar" );
            try
            {
                HDFSManager.instance().moveToLocal( src, tar );
                Tracer.debugTrace( HDFSViewServlet.class, "Move To local success : " + src + " -> " + tar, null );
                out.write( "1" );
                out.close();
            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Move to local failed : " + e.getMessage(), e );
                out.close();
            }
        }
        else if( "movefromlocal".equals( para ) )
        {
            String tar = request.getParameter( "tar" );
            if( tar.trim().startsWith( "/" ) )
            {
                tar = tar.substring( 1 );
            }
            tar = "/user/quintus/" + userContext.getIdentifier() + "/" + tar;
            String src = request.getParameter( "src" );
            try
            {
                HDFSManager.instance().copyFromLocalFile( src, tar );
                out.write( "1" );
                out.close();
                Tracer.debugTrace( HDFSViewServlet.class, "Move From Local success : " + src + " -> " + tar, null );
            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Move From local failed : " + e.getMessage(), e );
            }
        }
        else if( "copytolocal".equals( para ) )
        {
            String src = request.getParameter( "src" );
            String tar = request.getParameter( "tar" );
            tar = localPath + src;
            try
            {
                HDFSManager.instance().copyToLocalFile( src, tar );
                out.write( "1" );
                out.close();

            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Move To local failed : " + e.getMessage(), e );
                out.close();
            }
        }
        else if( "copyfromlocal".equals( para ) )
        {
            String src = request.getParameter( "src" );
            String tar = request.getParameter( "tar" );
            try
            {
                HDFSManager.instance().copyFromLocalFile( src, tar );

            }
            catch( IOException e )
            {
                Tracer.fatalTrace( HDFSViewServlet.class, "Move From local failed : " + e.getMessage(), e );
            }
        }
        /**
         * You should choose a HDFS path from HDFS directory tree first!
         * */
        else if( "filedata".equals( para ) )
        {
            int defaultCount = 100;
            String path = request.getParameter( "path" );
            if( path == null || path.equals( "" ) || path.equals( "null" ) )
            {
                out.close();
                return;
            }
            List<Map<String, String>> lines = HDFSManager.instance().getHDFSData( path, defaultCount );

            String json = JsonHelper.getNewInstance().toJson( lines );
            Tracer.debugTrace( HDFSViewServlet.class, "hdfs data json : " + json, null );

            out.write( json );
            out.flush();
            out.close();
        }
    }
}
